package br.com.while42.rpgcs.reflection; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import android.content.Context; import android.content.ContextWrapper; import android.content.pm.PackageManager.NameNotFoundException; import android.util.Log; import dalvik.system.DexClassLoader; import dalvik.system.DexFile; import dalvik.system.PathClassLoader; public class ClassByReflection { // public static final String PACKAGE = "br.com.while42.rpgcs"; private static Map<String, List<?>> cache = new HashMap<String, List<?>>(); @SuppressWarnings("unchecked") public static <T, K> List<K> getAll(Context context, Class<T> superc) { if (cache.containsKey(superc.getCanonicalName())) { Log.d("CACHE", "GET"); return (List<K>) cache.get(superc.getCanonicalName()); } String packageName = context.getPackageName(); Log.d("PACKAGE", packageName); String apkName; List<K> list = new ArrayList<K>(); try { apkName = context.getPackageManager().getApplicationInfo(packageName, 0).sourceDir; } catch (NameNotFoundException e1) { Log.d("DEBUG", e1.getMessage()); return list; } DexFile dexFile; try { dexFile = new DexFile(apkName); } catch (IOException e1) { Log.d("DEBUG", e1.getMessage()); return list; } ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); String absolutePath = new ContextWrapper(context).getCacheDir().getAbsolutePath(); PathClassLoader pathClassLoader = new PathClassLoader(apkName, contextClassLoader); DexClassLoader dexClassLoader = new DexClassLoader(apkName, absolutePath, null, pathClassLoader); Enumeration<String> entries = dexFile.entries(); while (entries.hasMoreElements()) { String entry = entries.nextElement(); // only check items that exists in source package (not in libraries) if (entry.startsWith(packageName)) { Class<?> entryClass; try { entryClass = dexClassLoader.loadClass(entry); // dexFile.loadClass(entry, } catch (ClassNotFoundException e) { Log.d("DEBUG", e.getMessage()); continue; } if (entryClass != null && !entryClass.isInterface() && !Modifier.isAbstract(entryClass.getModifiers())) { boolean isPublic = false; Constructor<?>[] constructors = entryClass.getConstructors(); for (Constructor<?> c : constructors) { isPublic = Modifier.isPublic(c.getModifiers()); } if (!isPublic) { continue; } Class<?> superclass = entryClass.getSuperclass(); while (superclass != null && superclass != superc) { superclass = superclass.getSuperclass(); } if (superclass != null && superclass == superc) { try { K obj = (K) entryClass.newInstance(); list.add(obj); } catch (InstantiationException e) { Log.d("DEBUG", e.getMessage()); e.printStackTrace(); } catch (IllegalAccessException e) { Log.d("DEBUG", e.getMessage()); e.printStackTrace(); } } } } } Log.d("CACHE", "PUT"); cache.put(superc.getCanonicalName(), new ArrayList<K>(list)); return list; } }